package com.hqbzl.c1.pc;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
public class Test {
    public static void s(long sec) {
        try {
            TimeUnit.SECONDS.sleep(sec);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Exchange exchange = new Exchange(10, 5, 1);
//        new Thread(() -> {
//            final String take = exchange.take();
//            log.debug("{}", take);
//        }, "take").start();
////        s(1);
//        new Thread(() -> {
//            exchange.push("12222");
//        }, "push").start();
        exchange.start();
//        int i = 0;
//        while (true) {
//            exchange.push("msg-" + i);
//            i++;
//        }
//        exchange.push(UUID.randomUUID().toString());
    }

    static class PushWorker extends Thread {
        private Exchange exchange;
        int index = 0;

        public PushWorker(Exchange exchange, String name) {
            this.exchange = exchange;
            setName(name);
        }

        @Override
        public void run() {
            int i = 0;
            while (true) {
                if (i >= 20) {
                    break;
                }
                exchange.push(UUID.randomUUID().toString() + "-" + Thread.currentThread().getId() + "-" + exchange.gid());
                i++;
            }
        }
    }

    static class TakeWorker extends Thread {
        private Exchange exchange;

        public TakeWorker(Exchange exchange, String name) {
            this.exchange = exchange;
            setName(name);
        }

        @Override
        public void run() {
            while (true) {
                final String take = exchange.take();
                log.debug("take: {}", take);
            }
        }
    }

    static class Exchange {
        final List<String> list = new ArrayList<>();
        private int length = 2;
        private PushWorker pushWorker;
        private TakeWorker takeWorker;
        // 内容
        // 生产者
        private int pm;
        // 消费者
        private int tm;

        Exchange(int length, int pm, int tm) {
            this.length = length;
            this.pm = pm;
            this.tm = tm;
        }

        int index = 0;

        public synchronized int gid() {
            return (index++);
        }

        public void start() {
            for (int i = 0; i < tm; i++) {
                new TakeWorker(this, "t-" + i).start();
            }
            for (int i = 0; i < pm; i++) {
                new PushWorker(this, "p-" + i).start();
            }
        }

        public void push(String value) {

            synchronized (this) {
                if (list.size() >= length) {
                    log.debug(" ======================> 队列已满，等待消费");
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.debug("放入数据:  {}", value);
                list.add(value);
//                this.notify();
                this.notifyAll();
            }
        }

        public String take() {
            synchronized (this) {
                while (list.isEmpty()) {
                    try {
                        this.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                String tValue = list.remove(0);
                this.notifyAll();
                return tValue;
            }
        }
    }
}
